package org.beynet.docs.ui;
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * GSyncMainFrame.java
 *
 * Created on 10 d√©c. 2011, 17:22:38
 */
import java.io.File;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import javax.security.auth.Subject;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
import javax.swing.JFileChooser;
import javax.swing.table.TableColumn;
import org.beynet.docs.format.Collection;

import org.beynet.docs.options.CommandLineOptions;
import org.beynet.docs.session.SessionFactory;
import org.beynet.docs.sync.FileSync;
import org.beynet.docs.sync.FileToSync;

/**
 *
 * @author beynet
 */
public class GSyncMainFrame extends javax.swing.JFrame {

    /**
     * 
     */
    private static final long serialVersionUID = 1089170282208099227L;

    /** Creates new form GSyncMainFrame */
    public GSyncMainFrame() {
        this.loginCtx = null;
        filesToSync = new javax.swing.JFileChooser();
        filesToSync.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
        fileUploadingTableModel = new FileUploadingTableModel();
        options = null;
        initComponents();
    }
    
    public LoginContext getLoginContext() {
        if (loginCtx == null) {
                try {
                    loginCtx = new LoginContext("GSync", new PassWord(this, true));
                    loginCtx.login();
                } catch (LoginException e) {
                    e.printStackTrace();
                    System.exit(1);
                }
            }
        return(this.loginCtx);
    }
    public void setLoginContext(LoginContext ctx) {
        this.loginCtx = ctx;
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jScrollPane1 = new javax.swing.JScrollPane();
        selectedFiles = new javax.swing.JTable();
        jMenuBar1 = new javax.swing.JMenuBar();
        jMenu1 = new javax.swing.JMenu();
        selectFileMenuItem = new javax.swing.JMenuItem();
        showOptions = new javax.swing.JMenuItem();
        startSyncMenuItem = new javax.swing.JMenuItem();
        clearSelection = new javax.swing.JMenuItem();
        exitMenuItem = new javax.swing.JMenuItem();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        selectedFiles.setModel(fileUploadingTableModel);
        TableColumn column = selectedFiles.getColumnModel().getColumn(2);
        column.setCellRenderer(new FileUploadRenderer());
        jScrollPane1.setViewportView(selectedFiles);

        jMenu1.setText("GSync");

        selectFileMenuItem.setText("Select Files to Sync");
        selectFileMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                selectFileMenuItemActionPerformed(evt);
            }
        });
        jMenu1.add(selectFileMenuItem);

        showOptions.setText("Options");
        showOptions.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                showOptionsActionPerformed(evt);
            }
        });
        jMenu1.add(showOptions);

        startSyncMenuItem.setText("Start Sync");
        startSyncMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                startSyncMenuItemActionPerformed(evt);
            }
        });
        jMenu1.add(startSyncMenuItem);

        clearSelection.setText("Clear Selected Files");
        clearSelection.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                clearSelectionActionPerformed(evt);
            }
        });
        jMenu1.add(clearSelection);

        exitMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_Q, java.awt.event.InputEvent.META_MASK));
        exitMenuItem.setText("Exit");
        exitMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                exitMenuItemActionPerformed(evt);
            }
        });
        jMenu1.add(exitMenuItem);

        jMenuBar1.add(jMenu1);

        setJMenuBar(jMenuBar1);

        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(jScrollPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 657, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(jScrollPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 440, Short.MAX_VALUE)
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

private void exitMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exitMenuItemActionPerformed
    System.exit(0);// TODO add your handling code here:
}//GEN-LAST:event_exitMenuItemActionPerformed

private void selectFileMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_selectFileMenuItemActionPerformed
    if (filesToSync.isVisible()) {
        int returnVal = filesToSync.showOpenDialog(this);
        if (returnVal == JFileChooser.APPROVE_OPTION) {
            File file = filesToSync.getSelectedFile();
            FileToSync f = new FileToSync(file);
            f.addObserver(fileUploadingTableModel);
            fileUploadingTableModel.addFileToObserver(f);
        }
    } else {
        filesToSync.setVisible(true);
    }
    this.pack();
}//GEN-LAST:event_selectFileMenuItemActionPerformed

private void showOptionsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_showOptionsActionPerformed
    if (options == null) {
        options = new OptionsSelector(this, true);
    }
    options.setVisible(true);
}//GEN-LAST:event_showOptionsActionPerformed

private void startSyncMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_startSyncMenuItemActionPerformed
    running = new SyncTask(this);
    running.start();
}//GEN-LAST:event_startSyncMenuItemActionPerformed

private void clearSelectionActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_clearSelectionActionPerformed
// TODO add your handling code here:
    if (running != null && running.isAlive() == true) {
        running.interrupt();
        while (running.isAlive()) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException ex) {
                   
                }
        }
    }
    fileUploadingTableModel.clearFiles();
}//GEN-LAST:event_clearSelectionActionPerformed

    class SyncTask extends Thread {

        protected SyncTask(GSyncMainFrame current) {
            this.current = current;
        }

        @Override
        public void run() {
            startSyncMenuItem.setEnabled(false);
            ExecutorService executor = null;
            current.getLoginContext();
            try {
                CommandLineOptions cmd = new CommandLineOptions(options.getOptions(), System.out);
                executor = new ThreadPoolExecutor(cmd.getMaxUploadThreads().intValue(),
                        cmd.getMaxUploadThreads().intValue(), 0,
                        TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
                FileSync syncOp = null;
                
                
                if (cmd.resume()) {
                    syncOp = new FileSync(cmd,executor,fileUploadingTableModel);
                }
                else {
                    List<FileToSync> startList = new ArrayList<FileToSync>();
                    startList.addAll(fileUploadingTableModel.toBeSynced);
                    syncOp = new FileSync(true, startList, fileUploadingTableModel, cmd.getDestinationFolder(), cmd, executor);
                }
                Subject.doAs(loginCtx.getSubject(), syncOp);
                if (Thread.currentThread().isInterrupted()) {
                    executor.shutdownNow();
                } else {
                    executor.shutdown();
                }
                
                boolean result = false;
                do {
                    try {
                        result = executor.awaitTermination(10, TimeUnit.SECONDS);
                    } catch (InterruptedException e) {
                        executor.shutdownNow();
                    }
                } while (result == false);

            } catch (Exception e) {
                e.printStackTrace();

            } finally {
                startSyncMenuItem.setEnabled(true);
            }

        }
        GSyncMainFrame current;
    }

    /**
     * @param args the command line arguments
     */
    public void start() {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(GSyncMainFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(GSyncMainFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(GSyncMainFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(GSyncMainFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                new GSyncMainFrame().setVisible(true);
            }
        });
    }
    javax.swing.JFileChooser filesToSync;
    FileUploadingTableModel fileUploadingTableModel;
    OptionsSelector options;
    private LoginContext loginCtx;
    private SyncTask running = null;
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JMenuItem clearSelection;
    private javax.swing.JMenuItem exitMenuItem;
    private javax.swing.JMenu jMenu1;
    private javax.swing.JMenuBar jMenuBar1;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JMenuItem selectFileMenuItem;
    private javax.swing.JTable selectedFiles;
    private javax.swing.JMenuItem showOptions;
    private javax.swing.JMenuItem startSyncMenuItem;
    // End of variables declaration//GEN-END:variables
}
